#include <string.h>

#include "lib.h"
#include "msgoutlt.h"

MsgOutlets::MsgOutlets()
{
	maxlen = 0;
	numOutlets = 0;
	outlets = (char**)0;
}

MsgOutlets::~MsgOutlets()
{
	if (outlets)
	{
		int32 i;

		for (i = 0; i < numOutlets; i++)
			delete [] outlets[i];

		delete [] outlets;
		outlets = (char**)0;
	}
}

void
MsgOutlets::add(char* outlet, uint8 id)
{
	if (outlet)
	{
		int32 len = strlen(outlet);

		if (len > 0 && len < 256)
		{
			char** newOutlets = new char*[numOutlets+1];

			if (newOutlets)
			{
				char* newOutlet;
				int32 i;

				if (outlets)
					memcpy(newOutlets, outlets, numOutlets * sizeof(char*));

				newOutlet = new char[1 + len + 1 + 1];
				
				if (newOutlet)
				{
					newOutlet[0] = (char)(uint8)(len & 0xff);
					memcpy(newOutlet + 1, outlet, len + 1);
					newOutlet[1 + len + 1] = id;

					if (len > maxlen)
						maxlen = len;

					// insertion sort
					//
					i = 0;
					while (i < numOutlets &&
						strcmpi(newOutlets[i], newOutlet) < 0)
						++i;

					if (i < numOutlets)
						memmove(newOutlets + i + 1, newOutlets + i,
							(numOutlets - i) * sizeof(char*));

					newOutlets[i] = newOutlet;
					++numOutlets;
				}
					
				delete [] outlets;
				outlets = newOutlets;
			}
		}
	}
}

int32
MsgOutlets::find(char* outlet, int32 len)
{
	if (outlet && len)
	{
		int32 lo, mid, hi, diff;
		uint8 blen = (uint8)(len & 0xff);

		lo = 0;
		hi = numOutlets - 1;

		while (lo <= hi)
		{
			mid = lo + ((hi - lo) >> 1);

			if (blen == (uint8)outlets[mid][0])
			{
				diff = _memicmp(outlet, outlets[mid] + 1, blen);

				if (diff == 0)
					return mid;
				else if (diff < 0)
					hi = mid - 1;
				else
					lo = mid + 1;
			}
			else if (blen < (uint8)outlets[mid][0])
				hi = mid - 1;
			else
				lo = mid + 1;
		}
	}
	return -1;
}

int32
MsgOutlets::find(char* outlet)
{
	if (outlet)
		return find(outlet, strlen(outlet) & 0xff);
	return -1;
}
